home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FishMarket 1.0
/
FishMarket v1.0.iso
/
fishies
/
051-075
/
disk_069
/
monproc
/
monproc.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-05-06
|
6KB
|
249 lines
/* monproc.c - monitor amigados process packet activity.
*
* Phillip Lindsay (c) 1987 Commodore-Amiga, Inc.
*
*/
#include <exec/types.h>
#include <exec/nodes.h>
#include <exec/lists.h>
#include <exec/memory.h>
#include <exec/ports.h>
#include <exec/tasks.h>
#include <exec/semaphores.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>
#include <libraries/filehandler.h>
#ifdef MANX
#include <functions.h>
#else
#define index stpchr /* can you say "ANSI STANDARD"...I knew you could... */
#endif
#include <stdio.h>
/* constants */
#define ONE 1L
/* AmigaDOS uses task signal bit 8 for message signaling */
#define DOS_SIGNAL 8
#define DOS_MASK ( ONE << DOS_SIGNAL )
/* referenced globals */
extern void getprocs(),freeprocs(),givepkt();
void memfill();
extern struct DosLibrary *DOSBase;
struct Message *packetwait();
LONG pw(); /* this the asm stub that calls packetwait() */
/* global data structures */
struct MsgPort *deviceid;
struct Process *memyselfNi;
ULONG mymask;
struct SignalSemaphore canreturn;
struct Message *mymess;
main()
{
struct List procs;
struct Node *proc;
register struct Process *devproc;
register struct DosPacket *pkt;
BYTE mypri;
register ULONG waitmask,signals,oldpktwait;
LONG mysignal;
ULONG count,choice;
UBYTE processname[81];
puts("MONPROC - monitor AmigaDOS process packet activity.\n");
memyselfNi = (struct Process *) FindTask(NULL);
NewList(&procs); /* initialize list header */
getprocs(&procs); /* fill list with "active" devices */
if(procs.lh_TailPred == &procs) /* list empty (should never happen) */
{
puts("No processes.");
exit(0);
}
/*
* I am assuming that process list won't change. This is for hackers only.
*/
do
{
puts("Enter NUMBER for process to monitor:");
puts("Pick# Process MsgPort Name");
for(count = 1,proc = procs.lh_Head;proc->ln_Succ;proc=proc->ln_Succ,count++)
printf("%4ld. %08lx %08lx %s\n",count,
((struct Process *)proc->ln_Name),
&(((struct Process *)proc->ln_Name)->pr_MsgPort),
((struct Process *)proc->ln_Name)->pr_Task.tc_Node.ln_Name);
printf("\nNUMBER: ");
fflush(stdout);
} while( scanf("%ld",&choice) == EOF ) ;
if(!choice || choice >= count)
{
puts("Operation aborted.");
freeprocs(&procs);
exit(0);
}
/* what did he/she pick? */
for(count = 1,proc = procs.lh_Head;proc->ln_Succ;proc=proc->ln_Succ,count++)
if(choice == count)
{
devproc = (struct Process *) proc->ln_Name;
break;
}
/* we don't need our process list anymore */
freeprocs(&procs);
/* make a copy of the process name */
strcpy(processname,devproc->pr_Task.tc_Node.ln_Name);
/* get process msgport of process we will be monitoring */
deviceid = &devproc->pr_MsgPort;
/* grab a signal for task intercommunication */
mysignal = (LONG) AllocSignal(-1L);
if(mysignal == -1)
{
puts("Can't allocate a task signal.");
exit(0);
}
mymask = ONE << mysignal;
waitmask = SIGBREAKF_CTRL_C | mymask;
/* initialize our semaphore */
memfill(&canreturn,(ULONG)sizeof(canreturn),0L);
InitSemaphore(&canreturn);
Forbid();
mypri = devproc->pr_Task.tc_Node.ln_Pri;
Permit();
/* make sure our priority is greater than the device task */
SetTaskPri(memyselfNi, (ULONG)(mypri+1) );
puts("Waiting for messages...[CTRL_C to quit monitoring...]");
/* install our packet wait function */
Forbid();
oldpktwait = (ULONG) devproc->pr_PktWait;
devproc->pr_PktWait = (APTR) pw;
Permit();
/*
* I am using semaphores to control the monitoring of the handler's packets.
* There is probably a hundred better ways of doing this. I just went with
* what first came to mind. Since I am a higher priority than the handler...
* Once I am awake I will obtain the semaphore before the lower priority
* task has a chance...I will give it back to him once I am done with the
* packet data structure.
*/
do
{
signals = (ULONG) Wait(waitmask);
ObtainSemaphore(&canreturn);
if(signals & mymask) /* did the packetwait code signal us? */
{ /* yes, let's boogie... */
pkt = (struct DosPacket *) mymess->mn_Node.ln_Name; /* get packet address */
printf("%s: ",processname);
givepkt(pkt);
}
ReleaseSemaphore(&canreturn);
} while(!(signals & SIGBREAKF_CTRL_C));
/* remove our packet wait function and install previous value */
Forbid();
devproc->pr_PktWait = (APTR) oldpktwait;
Permit();
SetTaskPri(memyselfNi,0L);
puts("\nThere is no safe way to leave since the process is waiting in");
puts("our installed code. We have de-installed ourselves, but you should");
puts("be certain that the process received a packet AFTER we have been");
puts("de-installed. Press CTRL-E if you are certain this has happened.");
Wait(SIGBREAKF_CTRL_E);
FreeSignal(mysignal);
puts("All done.");
} /* end of main() */
/**
** local subroutines
**/
/*
* packetwait() ... Waits for a message to arrive at your port and
* returns it to you.
*/
struct Message *packetwait()
{
#ifdef MANX /* if MANX make sure we can see our data */
geta4();
#endif
/* wait for packet */
SetSignal(FALSE,DOS_MASK); /* clear sigbit 8 */
while( !(mymess = (struct Message *) GetMsg(deviceid)) ) Wait(DOS_MASK);
Signal(memyselfNi,mymask); /* Wake up monitoring task he will grab the data */
ObtainSemaphore(&canreturn); /* we get this guy when we CAN return */
ReleaseSemaphore(&canreturn);
return(mymess);
}
/*
* memfill() - fill memory with supplied byte value for "size" bytes
*/
void memfill(source,size,value)
UBYTE *source;
ULONG size;
UBYTE value;
{
register UBYTE *msource=source,
mvalue=value;
register ULONG msize=size;
if(msize)
{
do
{
--msize;
msource[msize] = mvalue;
} while(msize);
}
}
/*
* This code stub has been known to save lives...
*/
#if MANX
#asm
XREF _packetwait
XDEF _pw
_pw:
movem.l a2/a3/a4,-(sp)
jsr _packetwait
movem.l (sp)+,a2/a3/a4
rts
#endasm
#endif
/* end of procdev.c */